const fs = require('fs');
const { PUBLIC_KEY_PATH, ALGORITHMS, PRIVATE_KEY_PATH } = require('../constant/jwt');
const jsonWebToken = require('jsonwebtoken');

/**
 * 生成JWTToken
 * @param {string | Buffer | object} payload 载荷
 * @param {string | number} expiresIn 过期时间，默认1h(number类型单位为秒)
 * @returns {string} JWTToken字符串
 */
function generateToken(payload, expiresIn = 60 * 60) {
    const privateKey = fs.readFileSync(PRIVATE_KEY_PATH);
    return jsonWebToken.sign(payload, privateKey, {
        expiresIn: expiresIn,
        algorithm: ALGORITHMS
    });
}

/**
 * 验证token是否正确，并返回解密数据
 * @param {string} token JWTToken
 * @returns {string | Buffer | object} 解密数据
 */
async function verifyToken(ctx, token) {
    const publicKey = fs.readFileSync(PUBLIC_KEY_PATH);
    const decodedToken = await jsonWebToken.verify(token, publicKey, {
        algorithms: ALGORITHMS
    });
    const { redis } = ctx;
    const { username } = decodedToken;
    const realToken = await redis.get(`refresh_token:${username}`);
    if (realToken === token) {
        return Promise.resolve(decodedToken);
    } else {
        return Promise.reject(new Error('refreshToken无效'));
    }
}

async function isRevoked(ctx, decodedToken, token) {
    const { redis } = ctx;
    const { username } = decodedToken;
    const realToken = await redis.get(`access_token:${username}`);
    return realToken !== token;
}

module.exports = {
    generateToken,
    verifyToken,
    isRevoked
};
